package com.bestcem.xm.user.controller;

import com.alibaba.fastjson.JSON;
import com.bestcem.xm.common.core.constant.AppRequestErrorCode;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.enums.AuthErrorCodeEnum;
import com.bestcem.xm.common.core.enums.ReqErrorCodeEnum;
import com.bestcem.xm.common.core.enums.ResourceErrorCodeEnum;
import com.bestcem.xm.component.security.annotation.XmAuth;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.component.security.dto.TokenDTO;
import com.bestcem.xm.user.controller.vo.order.PackOrderStatusVO;
import com.bestcem.xm.user.controller.vo.order.PackWeChatOrderVO;
import com.bestcem.xm.user.controller.vo.user.request.OfflineConfirmOrderVO;
import com.bestcem.xm.user.controller.vo.user.request.OfflineMakeOrderVO;
import com.bestcem.xm.user.enums.OrderTypeEnum;
import com.bestcem.xm.user.enums.OrgSourceEnum;
import com.bestcem.xm.user.enums.PackageTypeEnum;
import com.bestcem.xm.user.grpc.client.PackageGrpcService;
import com.bestcem.xm.user.grpc.client.UserPaymentGrpcService;
import com.bestcem.xm.user.grpc.client.dto.PackageDTO;
import com.bestcem.xm.user.mq.message.organization.OrgCreateMessage;
import com.bestcem.xm.user.service.OrderService;
import com.bestcem.xm.user.service.OrganizationService;
import com.bestcem.xm.user.service.UserMqConsumeService;
import com.bestcem.xm.user.service.UserService;
import com.bestcem.xm.user.service.dto.order.PackOrderStatusDTO;
import com.bestcem.xm.user.service.dto.order.PackWeChatOrderDTO;
import com.bestcem.xm.user.service.dto.user.OrganizationDTO;
import com.bestcem.xm.user.service.dto.user.UserDTO;
import com.bestcem.xm.user.service.dto.user.WxMackOrderDTO;
import com.bestcem.xm.user.util.convert.UserOrderConvert;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Objects;

/**
 * 官网首页支付、转账相关接口
 *
 * @author panyun <yun.pan@idiaoyan.com>
 * @version v1.0
 * @date 2022/5/6 11:03
 */
@Slf4j
@RestController
@RequestMapping("/user/pack")
public class UserOrderController {

    @Resource
    private UserPaymentGrpcService userPaymentGrpcService;

    @Resource
    private OrganizationService organizationService;

    @Resource
    private UserService userService;

    @Resource
    private OrderService orderService;

    @Resource
    private UserOrderConvert userOrderConvert;

    @Resource
    private UserMqConsumeService userMqConsumeService;

    @Resource
    private PackageGrpcService packageGrpcService;

    /**
     * 官网首页版本购买对公转账 : 线下支付 创建订单
     *
     * @param vo 折扣百分比
     * @return com.bestcem.xm.util.XmResultJson<java.lang.String>
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/5/6 17:25
     */
    @PostMapping("/offline/make/order/")
    @XmAuth
    public XmResultJson<HashMap<String, String>> offlineMakeOrder(@RequestBody OfflineMakeOrderVO vo) {
        if (Objects.isNull(PackageTypeEnum.getByType(vo.getPackType()))) {
            return XmResultJson.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "pack_type不正确，套餐不存在");
        }
        if (vo.getDuration() < 1) {
            return XmResultJson.fail(AppRequestErrorCode.PARAM_FORMAT, "duration is less than 0");
        }
        TokenDTO currentToken = SecurityContextHolder.getToken();
        String orgId = currentToken.getOrgId();
        String userId = currentToken.getUserId();

        ServiceResult<OrganizationDTO> orgResult = organizationService.selectByPrimaryKey(orgId);
        OrganizationDTO org = orgResult.getData();
        if (Objects.isNull(org)) {
            return XmResultJson.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "org_code is not exists");
        }
        if (OrgSourceEnum.OPENPLATFORM.getType().equals(org.getSource())) {
            return XmResultJson.fail(ResourceErrorCodeEnum.PERMISSION_DENY, "请联系合作伙伴");
        }
        if (StringUtils.isBlank(org.getCorpWallet())) {
            OrgCreateMessage message = new OrgCreateMessage();
            message.setOrgId(org.getOrgId());
            userMqConsumeService.orgCreateMessageListener(message);
        }

        ServiceResult<UserDTO> userResult = userService.selectById(userId);

        PackageDTO packageDTO = packageGrpcService.getByType(vo.getPackType());
        if (Objects.isNull(packageDTO)) {
            return XmResultJson.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "package is not exists");
        }

        String subject = "倍市得版本购买";
        String desc = "版本购买-" + PackageTypeEnum.getByType(vo.getPackType()).getDesc();
        int totalMount = packageDTO.getPrice() * vo.getDuration();
        HashMap<String, Integer> map = new HashMap<>(16);
        map.put("pack_type", vo.getPackType());
        map.put("duration", vo.getDuration());
        String extra = JSON.toJSONString(map);

        // 通过企业钱包grpc获取orderId
        String orderNo = userPaymentGrpcService.createOfflineOrder(OrderTypeEnum.ORDER_TYPE_BESTCEM_PURCHASE.getType(), subject, desc,
                userResult.getData(), org, totalMount, extra);
        if (Objects.isNull(orderNo)) {
            return XmResultJson.fail(ResourceErrorCodeEnum.THIRD_PART, "创建版本购买订单失败");
        }
        HashMap<String, String> hashMap = new HashMap<>(16);
        hashMap.put("order_id", orderNo);
        return XmResultJson.success(hashMap);
    }

    /**
     * 官网首页版本购买对公转账确认
     * 线下订单用户确认支付 通知销售
     *
     * @param vo 订单号
     * @return com.bestcem.xm.util.XmResultJson<java.lang.String>
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/5/12 17:43
     */
    @PostMapping("/offline/confirm/order/")
    @XmAuth
    public XmResultJson<String> offlineConfirmOrder(@Valid @RequestBody OfflineConfirmOrderVO vo) {
        ServiceResult<String> result = orderService.offlineConfirmOrder(vo.getOrderId());
        if (!result.isSuccess()) {
            return XmResultJson.fail(result.getErrorData(), result.getMsg());
        }
        return XmResultJson.success(vo.getOrderId());
    }


    /**
     * 获取套餐购买支付二维码
     * apps_mysql/user/user_handlers.py:160
     *
     * @param orderVO
     * @return com.bestcem.xm.util.XmResultJson<java.lang.Object>
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/05/30 13:49
     */
    @PostMapping("/wechat/make/order/")
    @XmAuth
    public XmResultJson<Object> packWechatMackOrder(@RequestBody @Validated PackWeChatOrderVO orderVO,
                                                    @RequestParam(value = "session_id", required = false) String sessionId) {
        String userId = SecurityContextHolder.getToken().getUserId();
        String orgId = SecurityContextHolder.getToken().getOrgId();
        if (orderVO.getDuration() < 1) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "duration is less than 0");
        }
        PackWeChatOrderDTO orderDTO = userOrderConvert.packWeChatOrderVo2Dto(orderVO);
        orderDTO.setUserId(userId);
        orderDTO.setOrgId(orgId);
        if (StringUtils.isNotBlank(sessionId)) {
            orderDTO.setSessionId(sessionId);
        }
        ServiceResult<Object> result = orderService.packWechatMackOrder(orderDTO);
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());

    }

    /**
     * 获取套餐升级微信订单支付状态
     * 1 创建订单的支付流程会有两个轮询，
     * 1 前端页面轮询订单状态，调用接口升级
     * 2 后端创建订单后会轮询该订单的状态，决定是否升级
     * apps_mysql/user/user_handlers.py:279
     *
     * @param orderId
     * @return com.bestcem.xm.util.XmResultJson<java.lang.Object>
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/05/30 13:50
     */
    @GetMapping("/get_order_status/")
    @XmAuth
    public XmResultJson<PackOrderStatusVO> getPackOrderStatus(@RequestParam("order_id") String orderId) {
        if (log.isInfoEnabled()) {
            log.error("[USER]get_order_status开始执行...");
        }
        if (StringUtils.isBlank(orderId)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "order_id is not");
        }
        ServiceResult<PackOrderStatusDTO> result = orderService.getPackOrderStatus(orderId);
        if (result.isSuccess()) {
            if (log.isInfoEnabled()) {
                log.error("[USER]get_order_status执行结束...");
            }
            return XmResultJson.success(userOrderConvert.orderStatusDTO2VO(result.getData()));
        }
        if (log.isInfoEnabled()) {
            log.error("[USER]get_order_status执行结束...");
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }


    /**
     * 双十一专业版体验 (已下架)
     *
     * @param packType
     * @param duration
     * @return com.bestcem.xm.util.XmResultJson<java.lang.Object>
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/05/30 13:50
     */
    @PostMapping("/wechat/make/order/trial/")
    public XmResultJson<Object> trialPackWechatMackOrder(@RequestParam Integer packType, @RequestParam Integer duration, @RequestParam(value = "session_id", required = false) String sessionId) {
        WxMackOrderDTO orderDTO = new WxMackOrderDTO();
        orderDTO.setPackType(packType);
        orderDTO.setPackDuration(duration);
        orderDTO.setSessionId(sessionId);
        orderDTO.setUserId(SecurityContextHolder.getToken().getUserId());
        orderDTO.setOrgId(SecurityContextHolder.getToken().getOrgId());
        ServiceResult<Object> result = orderService.trialPackWechatMackOrder(orderDTO);
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());

    }

    /**
     * 高级版，专业版四折购买  (已下架)
     *
     * @param packType
     * @param duration
     * @return com.bestcem.xm.util.XmResultJson<java.lang.Object>
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/05/30 13:50
     */
    @PostMapping("/wechat/make/order/discount/")
    public XmResultJson<Object> discountPackWechatMackOrder(@RequestParam Integer packType, @RequestParam Integer duration, @RequestParam(value = "session_id", required = false) String sessionId) {
        WxMackOrderDTO orderDTO = new WxMackOrderDTO();
        orderDTO.setPackType(packType);
        orderDTO.setPackDuration(duration);
        orderDTO.setSessionId(sessionId);
        orderDTO.setUserId(SecurityContextHolder.getToken().getUserId());
        orderDTO.setOrgId(SecurityContextHolder.getToken().getOrgId());
        ServiceResult<Object> result = orderService.discountPackWechatMackOrder(orderDTO);
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());

    }


    /**
     * 高级版，专业版四折购买 线下支付创建订单  (已下架)
     *
     * @param packType
     * @param duration
     * @return com.bestcem.xm.util.XmResultJson<java.lang.Object>
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/05/30 13:50
     */
    @PostMapping("/offline/make/order/discount/")
    public XmResultJson<Object> discountOfflineMakeOrder(@RequestParam Integer packType, @RequestParam Integer duration, @RequestParam(value = "session_id", required = false) String sessionId) {
        WxMackOrderDTO orderDTO = new WxMackOrderDTO();
        orderDTO.setPackType(packType);
        orderDTO.setPackDuration(duration);
        orderDTO.setSessionId(sessionId);
        orderDTO.setUserId(SecurityContextHolder.getToken().getUserId());
        orderDTO.setOrgId(SecurityContextHolder.getToken().getOrgId());
        ServiceResult<Object> result = orderService.discountOfflineMakeOrder(orderDTO);
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());

    }

}
